<template>
	<uni-popup ref="picker" type="bottom" :safe-area="false">
		<view class="date_picker">
			<view class="title">选择时间</view>
			<!-- 日期 -->
			<template v-if="active===0">
				<picker-view :value="val" class="picker-view" indicator-style="height:56px;" indicator-class="active"
					immediate-change @change="changeDate">
					<picker-view-column>
						<view :class="{item:true,'active_item':val[0]==index}" v-for="(item, index) in years"
							:key="index">{{ item }}</view>
					</picker-view-column>
					<picker-view-column>
						<view :class="{item:true,'active_item':val[1]==index}" v-for="(item, index) in months"
							:key="index">
							{{ item.toString().padStart(2, '0') }}
						</view>
					</picker-view-column>
					<picker-view-column>
						<view :class="{item:true,'active_item':val[2]==index}" v-for="(item, index) in days"
							:key="index">
							{{ item.toString().padStart(2, '0') }}
						</view>
					</picker-view-column>
				</picker-view>
			</template>
			<!-- 时分 -->
			<template v-if="active===1">
				<picker-view :value="val1" indicator-style="height:52px" indicator-class="active"
					class="picker-view picker_time" immediate-change @change="changeTime">
					<picker-view-column>
						<view :class="{item:true,'active_item':val1[0]==index}" v-for="(item, index) in hours"
							:key="index">
							{{ item.toString().padStart(2, '0') }}
						</view>
					</picker-view-column>
					<picker-view-column>
						<view :class="{item:true,'active_item':val1[1]==index}" v-for="(item, index) in minutes"
							:key="index">
							{{ item.toString().padStart(2, '0') }}
						</view>
					</picker-view-column>
				</picker-view>
			</template>
			<view class="operation">
				<button class="cancel_btn" @tap="cancel">取消</button>
				<button class="confirm_btn" @tap="confirm">确定</button>
			</view>
		</view>
	</uni-popup>
</template>

<script setup lang="ts">
	import { nextTick, onMounted, ref } from 'vue';

	const props = withDefaults(
		defineProps<{
			modelValue : string;
			disabled ?: boolean;
		}>(),
		{
			disabled: false,
		}
	);
	const emits = defineEmits(['update:modelValue', 'confirm']);

	const active = ref(0); // 0 日期 1 时间
	const sendTime = ref('') // 日期时间
	const chooseDate = ref('')  // 日期
	const chooseTime = ref('')  // 时间
	const picker = ref();

	const val = ref<number[]>([0, 0, 0]);
	const val1 = ref<number[]>([0, 0]);

	const date = new Date();
	const now_year = date.getFullYear();
	const now_month = date.getMonth() + 1;
	const now_day = date.getDate();

	let now_hours = ref<number>()
	let now_minutes = ref<number>()

	const years = ref<number[]>([]);
	const months = ref<number[]>([]);
	const days = ref<number[]>([]);
	const hours = ref<number[]>([]);
	const minutes = ref<number[]>([]);
	let sameYear = ref(false)
	let sameMonth = ref(false)
	let sameDay = ref(false)


	// 时
	const setHours = (minHours : number) => {
		hours.value = []
		for (var i = minHours; i <= 23; i++) {
			hours.value.push(i);
		}
	}
	// 分
	const setMinutes = (minMinutes : number) => {
		minutes.value = []
		for (var i = minMinutes; i <= 59; i++) {
			minutes.value.push(i);
		}
	}
	// 年
	const setYears = () => {
		for (let i = now_year; i <= 2054; i++) {
			years.value.push(i);
		}
	}
	// 月
	const setMonths = (mixMonth ?: number) => {
		months.value = [];
		for (let i = mixMonth; i <= 12; i++) {
			months.value.push(i);
		}

	};
	// 日 
	const setDays = (...args : number[]) => {
		days.value = [];
		let total = 30;
		if ([1, 3, 5, 7, 8, 10, 12].includes(args[0])) {
			total = 31;
		} else if ([4, 6, 9, 11].includes(args[0])) {
			total = 30;
		} else {
			total = (args[1] % 4 === 0 && args[1] % 100 !== 0) || args[1] % 400 === 0 ? 29 : 28;
		}
		if (args.length === 3) {
			for (let i = args[2]; i <= total; i++) {
				days.value.push(i);
			}
		} else {
			for (let i = 1; i <= total; i++) {
				days.value.push(i);
			}
		}

	};
	// 有选中值时
	const setVal = async (time : string) => {
		const t = new Date(time);
		if (t.getFullYear() === now_year) {
			setMonths(now_month);
			t.getMonth() + 1 === now_month
				? setDays(now_month, t.getFullYear(), now_day)
				: setDays(t.getMonth() + 1, t.getFullYear());
		} else {
			setMonths(1);
			setDays(t.getMonth() + 1, t.getFullYear());
		}
		if (t.getFullYear() === now_year && t.getMonth() + 1 === now_month && t.getDate() === now_day) {
			setHours(now_hours.value)
			t.getHours() === now_hours.value ? setMinutes(now_minutes.value) : setMinutes(0)
		} else {
			setHours(0)
			setMinutes(0)
		}
		const yidx = years.value.indexOf(t.getFullYear());
		const hidx = hours.value.indexOf(t.getHours())
		const minidx = minutes.value.indexOf(t.getMinutes())
		const midx = months.value.indexOf(t.getMonth() + 1);
		const didx = days.value.indexOf(t.getDate());

		val.value = [yidx, midx, didx];
		val1.value = [hidx, minidx];
		await nextTick();
	};

	async function changeDate({ detail: { value } } : AnyObject) {
		const y = years.value[value[0]];
		let m = months.value[value[1]];
		let d = days.value[value[2]];
		let monthsIdx = 0
		let daysIdx = 0
		if (y === now_year) {
			setMonths(now_month)
			setDays(m, now_year, now_day);
			if (m === now_month) {
				setDays(now_month, now_year, now_day);
			} else {
				if (m < now_month) {
					setDays(m, now_year, now_day)
				} else {
					setDays(m, now_year)
				}
			}
			monthsIdx = months.value.findIndex((item : number) => item === m)
			value[1] = monthsIdx === -1 ? 0 : monthsIdx
			daysIdx = days.value.findIndex((item : number) => item === d)
			value[2] = daysIdx === -1 ? 0 : daysIdx
		} else {
			setMonths(1);
			setDays(m, y);
			value[1] = months.value.findIndex((item : number) => item === m)
			value[2] = days.value.findIndex((item : number) => item === d)
			await nextTick();
		}
		val.value = value;
		val1.value = [0, 0]  // 修改年月日
		chooseDate.value = `${years.value[val.value[0]]}/${(months.value[val.value[1]]).toString().padStart(2, '0')}/${(days.value[val.value[2]])
			.toString()
			.padStart(2, '0')}`;
	}

	async function changeTime({ detail: { value } } : AnyObject) {
		const h = (hours.value[value[0]])
		const m = (minutes.value[value[1]])
		if (sameYear.value && sameMonth.value && sameDay.value) {
			if (h === now_hours.value) {
				setMinutes(now_minutes.value)
			} else {
				setMinutes(0)
			}
			value[1] = minutes.value.findIndex((item : number) => item === m) === -1 ? 0 : minutes.value.findIndex((item : number) => item === m)
			await nextTick();
		}
		val1.value = value;
		chooseTime.value = `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}`
	}
	// 取消
	function cancel() {
		if (active.value === 1) {
			active.value = 0
			return
		}
		picker.value.close()
	}
	// 确认
	async function confirm() {
		if (active.value === 0) {
			if (!chooseDate.value) {
				chooseDate.value = `${years.value[val.value[0]]}/${(months.value[val.value[1]]).toString().padStart(2, '0')}/${(days.value[val.value[2]])
					.toString()
					.padStart(2, '0')}`;
			}
			now_minutes.value = date.getMinutes()
			now_hours.value = date.getHours()
			// 判断是否今日
			sameYear.value = new Date(chooseDate.value).getFullYear() === now_year;
			sameMonth.value = new Date(chooseDate.value).getMonth() + 1 === now_month;
			sameDay.value = new Date(chooseDate.value).getDate() === now_day;
			if (sameYear.value && sameMonth.value && sameDay.value) {
				setHours(now_hours.value)
				setMinutes(now_minutes.value)
				if (chooseTime.value) {
					if (now_hours.value === parseInt(chooseTime.value.split(':')[0], 10)) {
						setMinutes(now_minutes.value)
					} else {
						setMinutes(0)
					}
				}

			} else {
				setHours(0)
				setMinutes(0)
			}
			active.value = 1
			await nextTick()
			return
		}
		if (!chooseTime.value) {
			chooseTime.value = `${(hours.value[val1.value[0]]).toString().padStart(2, '0')}:${(minutes.value[val1.value[1]]).toString().padStart(2, '0')}`
		}
		sendTime.value = `${chooseDate.value} ${chooseTime.value}`
		picker.value.close()
		emits('confirm', sendTime.value);
		emits('update:modelValue', sendTime.value);


	}
	function open() {
		picker.value.open();
		active.value = 0;
		sendTime.value = props.modelValue
		setYears()
		setMonths(now_month);
		setDays(now_month, now_year, now_day);

		now_minutes.value = date.getMinutes()
		now_hours.value = date.getHours()
		setHours(now_hours.value)
		setMinutes(now_minutes.value)

		if (sendTime.value) {
			setVal(sendTime.value);
		}

	}
	defineExpose({
		open,
	});
</script>

<style lang="scss" scoped>
	.date_picker {
		position: relative;
		height: 576rpx;
		width: 750rpx;
		background-color: #fff;
		border-radius: 20rpx 20rpx 0rpx 0rpx;
		padding: 105rpx 0 0 0;
		box-sizing: border-box;

		.title {
			position: absolute;
			top: 30rpx;
			left: 30rpx;
			z-index: 99;
			color: #333;
			font-weight: 500;
			font-size: 32rpx;

		}


		.operation {
			display: flex;
			position: absolute;
			padding-top: 16rpx;
			bottom: 60rpx;
			left: 4rpx;
			width: 100%;
			box-sizing: border-box;

			button::after {
				border: none;
			}

			.cancel_btn {
				width: 230rpx;
				height: 90rpx;
				color: #615DFF;
				background-color: #ececff;
			}

			.confirm_btn {
				margin-left: 20rpx;
				height: 90rpx;
				width: 440rpx;
				color: #fff;
				background-color: #615DFF;
			}
		}
	}

	.picker-view {
		height: 280rpx;
		width: calc(100vw - 340rpx);
		margin: 30rpx 140rpx;
		padding: 0 30rpx;
		margin: auto;

		.item {
			line-height: 56px;
			text-align: center;
			margin: 0 5rpx;
			font-size: 40rpx;
			color: #666666;
		}

		.active_item {
			color: #333;
			font-weight: 500;
			font-size: 48rpx;
		}
	}


	.picker_time {
		width: calc(100vw - 572rpx);
	}

	:deep(.active) {
		border-top: 1px solid #eee;
		border-bottom: 1px solid #eee;
		color: #333;
		font-size: 48rpx;
		font-weight: 500;


	}
</style>